Gitea + Woodpecker CI 自动化部署教程

Posted by Forgus on 2026-03-30

在 k3s 集群内部署 Gitea 和 Woodpecker CI,实现代码推送后自动构建镜像并部署到 k3s。

架构

1
2
3
4
5
6
7
开发者 → Gitea (代码托管)
↓ Webhook
Woodpecker CI (流水线引擎)

构建镜像 → 推送 Zot 镜像仓库

kubectl 部署到 k3s

组件端口

组件 HTTP 端口 SSH 端口 命名空间 数据库
Gitea 30080 30022 gitea MySQL
Woodpecker Server 30800 - woodpecker SQLite
Woodpecker Agent - - woodpecker -
MySQL - - mysql -
Zot 30500 - zot-registry -

当前状态

所有组件已部署并运行正常:

1
2
3
4
5
gitea             gitea-85857cdbb6-sszxv    1/1  Running (已连接 MySQL)
mysql mysql-55bfb88477-fd486 1/1 Running
woodpecker woodpecker-server-xxx 1/1 Running
woodpecker woodpecker-agent-xxx 1/1 Running (Kubernetes 后端)
zot-registry zot-86fd87d57-28nxb 1/1 Running

快速开始

1. 访问 Gitea

直接访问 http://192.168.2.40:30080,Gitea 已自动完成初始化配置。

已自动配置的内容

  • ✅ 数据库:MySQL (mysql.mysql.svc.cluster.local:3306)
  • ✅ 数据库名:gitea
  • ✅ 数据库用户:gitea
  • ✅ 仓库根路径:/var/lib/gitea/git/repositories(存储在 Longhorn)
  • ✅ Git LFS 路径:/var/lib/gitea/git/lfs(存储在 Longhorn)
  • ✅ 日志路径:/var/lib/gitea/log(存储在 Longhorn)
  • ✅ 安装锁:已锁定(跳过安装向导)

首次登录

  1. 访问 http://192.168.2.40:30080
  2. 点击 登录,然后点击 注册 创建第一个管理员账户
  3. 第一个注册的账户自动成为管理员

2. 配置 Gitea OAuth 应用

  1. 登录 Gitea 后,点击右上角头像 → 设置应用管理 OAuth2 应用
  2. 点击 创建新的 OAuth2 应用,填写:
    • 应用名称Woodpecker CI
    • 重定向 URIhttp://192.168.2.40:30800/authorize
    • 保密性:保密(勾选)
  3. 创建后记录生成的 客户端 ID客户端密钥

3. 更新 Woodpecker OAuth 配置

1
2
cd /root/projects/woodpecker-deploy
./update-oauth.sh <CLIENT_ID> <CLIENT_SECRET> AGENT_SECRET_TOKEN

注意AGENT_SECRET_TOKEN 是当前 Server 和 Agent 共享的密钥,如需更换需同时更新 Server 和 Agent 配置。

4. 配置 Zot 镜像仓库认证

如果 Zot 设置了用户名密码认证,需要创建 Kubernetes Secret:

1
2
cd /root/projects/woodpecker-deploy
./create-zot-secret.sh 192.168.2.40:30500 <用户名> <密码>

如果 Zot 是公开访问(无认证),可以跳过此步骤。

5. 验证 Woodpecker 连接

访问 http://192.168.2.40:30800,使用 Gitea 账户登录。

  • 首次登录会自动通过 OAuth 同步 Gitea 仓库
  • Repositories 页面可以看到已同步的仓库
  • 点击仓库右侧的 启用 按钮激活 CI/CD

6. 部署示例应用

1
2
3
4
5
6
7
8
9
10
cd /root/projects/sample-app

# 初始化 Git 仓库
git init
git add .
git commit -m "初始提交"

# 在 Gitea 中创建 sample-app 仓库,然后推送
git remote add origin http://192.168.2.40:30080/<你的用户名>/sample-app.git
git push -u origin main

推送后,在 Woodpecker UI 中启用该仓库,流水线会自动触发。

配置新应用

1. 创建流水线配置

在仓库根目录创建 .woodpecker.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
steps:
build-and-push:
image: docker:dind
environment:
- ZOT_HOST=192.168.2.40:30500
- REPO_NAME=my-app
commands:
- docker build -t ${ZOT_HOST}/${REPO_NAME}:${CI_COMMIT_SHA} .
- docker push ${ZOT_HOST}/${REPO_NAME}:${CI_COMMIT_SHA}

deploy:
image: bitnami/kubectl:latest
environment:
- ZOT_HOST=192.168.2.40:30500
- REPO_NAME=my-app
- APP_NAME=my-app
commands:
- kubectl set image deployment/${APP_NAME} ${APP_NAME}=${ZOT_HOST}/${REPO_NAME}:${CI_COMMIT_SHA}
- kubectl rollout status deployment/${APP_NAME} --timeout=120s
when:
branch: main

2. 在 Woodpecker 中启用仓库

  1. 访问 http://192.168.2.40:30800
  2. 点击 Sync 同步最新仓库
  3. 找到目标仓库,点击 Enable

3. 配置仓库 Secrets(可选)

在仓库设置 → Secrets 中添加:

Secret 名称 说明
ZOT_HOST 192.168.2.40:30500 Zot 仓库地址
REPO_NAME my-app 镜像名称
APP_NAME my-app k8s Deployment 名称

4. 触发流水线

推送代码到 main 分支即可自动触发流水线。

目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
├── gitea-deploy/              # Gitea 部署文件
│ ├── k8s/
│ │ ├── namespace.yaml # 命名空间
│ │ ├── pvc.yaml # 持久化存储 (Longhorn)
│ │ ├── deployment.yaml # 部署配置 (已配置 MySQL)
│ │ └── service.yaml # 服务暴露
│ ├── deploy.sh # 部署脚本
│ └── configure-oauth.sh # OAuth 配置指南
├── woodpecker-deploy/ # Woodpecker 部署文件
│ ├── k8s/
│ │ ├── namespace.yaml # 命名空间
│ │ ├── rbac.yaml # RBAC 权限
│ │ ├── server.yaml # Server 部署
│ │ ├── agent.yaml # Agent 部署 (Kubernetes 后端)
│ │ ├── service.yaml # 服务暴露
│ │ └── zot-secret.yaml # 镜像仓库认证
│ ├── deploy.sh # 部署脚本
│ ├── update-oauth.sh # OAuth 配置更新
│ └── create-zot-secret.sh # Zot 认证创建
├── mysql-deploy/ # MySQL 部署文件
│ ├── k8s/
│ │ ├── namespace.yaml # 命名空间
│ │ ├── secret.yaml # 数据库密码
│ │ ├── pvc.yaml # 持久化存储 (Longhorn)
│ │ ├── deployment.yaml # 部署配置
│ │ └── service.yaml # 服务暴露
│ └── deploy.sh # 部署脚本
├── sample-app/ # 示例应用
│ ├── .woodpecker.yml # 流水线配置
│ ├── deployment.yaml # k8s 部署配置
│ ├── Dockerfile # 镜像构建
│ ├── index.html # 示例页面
│ └── README.md # 应用说明
├── deploy-all.sh # 一键部署脚本
├── verify-deployment.sh # 验证脚本
└── README.md # 本文档

数据库信息

MySQL 配置

项目
服务地址 mysql.mysql.svc.cluster.local:3306
数据库名 gitea
用户名 gitea
密码 默认密码
Root 密码 默认密码
存储 Longhorn (20Gi)

安全提示:生产环境请修改默认密码,见 mysql-deploy/k8s/secret.yaml

Gitea 路径说明

所有数据路径都存储在 Longhorn 持久化卷中:

路径 用途 说明
/var/lib/gitea/git/repositories 仓库根目录 存放所有 Git 仓库数据
/var/lib/gitea/git/lfs Git LFS 目录 存放大文件 (Git LFS 跟踪的文件)
/var/lib/gitea/log 日志目录 Gitea 运行日志
/var/lib/gitea/data 数据目录 附件、头像、Packages 等

Git LFS 是什么:Git Large File Storage,用于管理大文件(如图片、视频、二进制文件)的 Git 扩展。普通代码不需要 LFS,但如果仓库包含大文件,需要启用此功能。

常用命令

查看组件状态

1
2
3
4
5
# 查看所有 Pod
kubectl get pods -n gitea -n woodpecker -n zot-registry -n mysql

# 查看 Service
kubectl get svc -n gitea -n woodpecker -n zot-registry -n mysql

查看日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Gitea 日志
kubectl logs -n gitea -l app=gitea -f

# MySQL 日志
kubectl logs -n mysql -l app=mysql -f

# Woodpecker Server 日志
kubectl logs -n woodpecker -l app=woodpecker-server -f

# Woodpecker Agent 日志
kubectl logs -n woodpecker -l app=woodpecker-agent -f

# 流水线任务日志(在 woodpecker-jobs 命名空间)
kubectl logs -n woodpecker-jobs -l woodpecker.io/pipeline-id=<PIPELINE_ID> -f

重启组件

1
2
3
4
5
6
7
8
9
10
11
# 重启 Gitea
kubectl rollout restart deployment/gitea -n gitea

# 重启 MySQL
kubectl rollout restart deployment/mysql -n mysql

# 重启 Woodpecker Server
kubectl rollout restart deployment/woodpecker-server -n woodpecker

# 重启 Woodpecker Agent
kubectl rollout restart deployment/woodpecker-agent -n woodpecker

连接 MySQL

1
2
# 进入 MySQL 命令行
kubectl exec -it -n mysql deployment/mysql -- mysql -ugitea -p密码 gitea

技术说明

Woodpecker Agent 后端

当前使用 Kubernetes 后端,流水线步骤直接在 k3s 中创建 Pod 运行。

优点

  • 无需 Docker-in-Docker
  • 更好的资源隔离
  • 支持特权操作(通过配置)

配置

  • 任务命名空间:woodpecker-jobs
  • 存储类:longhorn
  • 存储大小:5Gi

k3s 节点配置

由于 Zot 使用 HTTP 无 TLS,每个 k3s 节点需要配置 insecure 仓库:

1
2
3
4
5
6
7
8
9
10
11
# 在每个节点上执行
sudo tee /etc/rancher/k3s/registries.yaml << EOF
mirrors:
"192.168.2.40:30500":
endpoint:
- "http://192.168.2.40:30500"
EOF

# 重启 k3s
sudo systemctl restart k3s # server 节点
sudo systemctl restart k3s-agent # agent 节点

故障排查

Gitea 无法连接数据库

  1. 检查 MySQL 是否运行:

    1
    kubectl get pods -n mysql
  2. 检查数据库凭据:

    1
    kubectl get secret -n mysql mysql-secret -o jsonpath='{.data}'

Woodpecker 无法连接 Gitea

  1. 检查 OAuth 配置是否正确:

    1
    kubectl get deployment woodpecker-server -n woodpecker -o jsonpath='{.spec.template.spec.containers[0].env}'
  2. 确认 Gitea 可访问:

    1
    curl http://192.168.2.40:30080

流水线失败:无法拉取镜像

  1. 检查 Zot 认证 Secret:

    1
    kubectl get secret zot-registry-secret -n woodpecker
  2. 确认 k3s 节点已配置 insecure 仓库

流水线失败:无法部署到 k8s

  1. 检查 RBAC 权限:

    1
    kubectl get role,rolebinding -n woodpecker
  2. 确认 ServiceAccount 正确配置

后续扩展

  • 多环境部署:配置 dev/staging/prod 不同命名空间
  • 镜像扫描:添加 Trivy 等安全扫描步骤
  • 通知集成:配置钉钉/企业微信/邮件通知
  • ArgoCD 集成:实现 GitOps 部署模式